package io.github.enbool.service;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import io.github.enbool.bean.query.OrganizationQuery;
import io.github.enbool.domain.Organization;
import io.github.enbool.exception.RecordNotFoundException;
import io.github.enbool.repository.OrganizationRepository;
import io.github.enbool.util.UserUtil;


@Service
public class OrganizationService {

	@Autowired
	private OrganizationRepository organizationRepository;
	
	public Organization findOne(Long id) {
		Organization organization = organizationRepository.findOne(id);
		if(organization == null) {
			throw new RecordNotFoundException("Organization", id);
		}
		return organization;
	}
	
	public Long delete(Long id) {
		Organization organization = organizationRepository.findOne(id);
		if(organization == null) {
			return -1L;
		}
		organization.setDeleted(true);
		save(organization);
		return id;
	}
	
	public Organization save(Organization organization) {
		if(organization.getId() == null) {
			organization.setCreateTime(Instant.now().toEpochMilli());
		}
		organization.setUpdateTime(Instant.now().toEpochMilli());
		return organizationRepository.save(organization);
	}
	
	
	public Organization me() {
		return UserUtil.getUserOrganization();
	}
	
		
	public Page<Organization> query(OrganizationQuery query, Pageable pageable){
		
		Specification<Organization> specification = new Specification<Organization>() {
			
			@Override
			public Predicate toPredicate(Root<Organization> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
				
				List<Predicate> predicates = new ArrayList<>();
					
						
				if(StringUtils.isNotBlank(query.getName())) {
					predicates.add(cb.like(root.<String>get("name"), "%" + query.getName() + "%"));
				}
				
				if (query.getDeleted() != null) {
					predicates.add(cb.equal(root.<Boolean>get("deleted"), query.getDeleted()));
				}
				
				if (query.getStart() != null) {
					predicates.add(cb.ge(root.<Long>get("createTime"), query.getStart()));
				}
				if (query.getEnd() != null) {
					predicates.add(cb.le(root.<Long>get("createTime"), query.getEnd()));
				}
				
				return cb.and(predicates.toArray(new Predicate[predicates.size()]));
			}
		};
		
		return organizationRepository.findAll(specification, pageable);	
	}
}
